/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SLE_CONNECT_HAL_H
#define SLE_CONNECT_HAL_H

#ifndef SLE_LOG_TAG
#define SLE_LOG_TAG "[SleHal]"
#endif

#include "sle_hal_errcode.h"
#include "sle_connect_config.h"
#include "sle_device_config.h"
#include "sle_connect_hdi.h"
#include <stddef.h>
#include <string.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Callback invoked when the SLE connect state changed.
 *
 * @param [in] connectId                   - Indicates the ID of the SLE connect.
 * @param [in] addr                     - Indicates the remote device's address.
 * @param [in] connState                - Indicate the connect state {@link SleConnectState}.
 * @param [in] discReason               - Indicate the disconnect reason {@link SleDisconnectReason}.
 * @return None
 */
typedef void (*SleHalChangeConnectStateCallback)(uint16_t connectId, const SleDeviceAddress *addr
        , SleAcbState connState, SlePairState pairState, SleDisConnectReason discReason);

/**
 * @brief Callback invoked when the SLE connect parameter change request is sent.
 *
 * @param [in] connectId                   - Indicates the ID of the SLE connection.
 * @param [in] errCode                  - Indicate the operation result status @link SleHalErrorCode
 * @param [in] connParam                - Indicate the connect parameter {@link SleConnectParam}.
 * @return None
 */
typedef void (*SleHalUpdateConnectParamReqCallback)(uint16_t connectId, SleHalErrorCode errCode, const SleConnectParam *connParam);

/**
 * @brief Callback invoked when the SLE connect parameter changed.
 *
 * @param [in] connectId                   - Indicates the ID of the SLE connection.
 * @param [in] errCode                  - Indicate the operation result status @link SleHalErrorCode
 * @param [in] connParam                - Indicate the connect parameter {@link SleConnectParam}.
 * @return None
 */
typedef void (*SleHalUpdateConnectParamCallback)(uint16_t connectId, SleHalErrorCode errCode, const SleConnectionParamUpdateEvt *connParam);

/**
 * @brief Callback invoked when the SLE Authentication complete.
 *
 * @param [in] connectId                   - Indicates the ID of the SLE connection.
 * @param [in] addr                     - Indicates the remote device's address.
 * @param [in] errCode                  - Indicate the operation result status @link SleHalErrorCode
 * @param [in] connParam                - Indicate the authenticate information {@link SleAuthenticateInfo}.
 * @return None
 */
typedef void (*SleHalAuthCompletedCallback)(uint16_t connectId, const SleDeviceAddress *addr, SleHalErrorCode errCode, const SleAuthInfo *authInfo);

/**
 * @brief Callback invoked when the SLE pair complete.
 *
 * @param [in] connectId                   - Indicates the ID of the SLE connection.
 * @param [in] addr                     - Indicates the remote device's address.
 * @param [in] errCode                  - Indicate the operation result status @link SleHalErrorCode
 * @return None
 */
typedef void (*SleHalPairCompleteCallback)(uint16_t connectId, const SleDeviceAddress *addr, SleHalErrorCode errCode);

/**
 * @brief Callback invoked when read rssi complete.
 *
 * @param [in] connectId                   - Indicates the ID of the SLE connection.
 * @param [in] rssi                     - Indicates the remote device's rssi value.
 * @param [in] errCode                  - Indicate the operation result status @link SleHalErrorCode
 * @return None
 */
typedef void (*SleHalReadRssiCompleteCallback)(uint16_t connectId, int8_t rssi, SleHalErrorCode errCode);

/**
 * @brief Callback invoked when set PHY complete.
 *
 * @param [in] connectId                   - Indicates the ID of the SLE connection.
 * @param [in] errCode                     - Indicate the operation result status @link SleHalErrorCode.
 * @param [in] status                      - current PHY parameters.
 * @return None
 */
typedef void (*SleHalSetPhyParamCallback)(uint16_t connectId, SleHalErrorCode ret, const SleConnectionPhyParam *param);

typedef struct {
    SleHalChangeConnectStateCallback OnConnectHalConnectStateChangeCb;
    SleHalUpdateConnectParamReqCallback OnConnectHalConnectParamUpdateReqCb;
    SleHalUpdateConnectParamCallback OnConnectHalConnectParamUpdateCompleteCb;
    SleHalAuthCompletedCallback OnConnectHalAuthCompleteCb;
    SleHalPairCompleteCallback OnConnectHalPairCompleteCb;
    SleHalReadRssiCompleteCallback OnConnectHalReadRssiCompleteCb;
    SleHalSetPhyParamCallback OnConnectHalSetPhyParamCompleteCb;
} SleConnectHalCallbacks;

/**
 * @brief   Initialize the SLE connect HAL.
 *
 * @param   None
 * @return  SleHalErrorCode
 */
SleHalErrorCode InitSleConnectHal(void);

/**
 * @brief   Deinitialize the SLE connect HAL.
 *
 * @param   None
 * @return  SleHalErrorCode
 */
SleHalErrorCode DeinitSleConnectHal(void);

/**
 * @brief   Connect to the remote device.
 *
 * @param   [in] address                - Indicates the remote device's address.
 * @return  SleHalErrorCode
 *
 * @note    result returns in @link SleHalChangeConnectStateCallback
 */
SleHalErrorCode SleConnectHalConnect(const SleDeviceAddress *address);

/**
 * @brief   Disconnect from the remote device.
 *
 * @param   [in] address                - Indicates the remote device's address.
 * @return  SleHalErrorCode
 *
 * @note    result returns in @link SleHalChangeConnectStateCallback
 */
SleHalErrorCode SleConnectHalDisconnect(const SleDeviceAddress *address);

/**
 * brief   Update the connect parameter.
 *
 * @param   [in] connectId                 - Indicates the ID of the SLE connect.
 * @param   [in] param                  - Indicates the connect parameter {@link SleConnectParam}.
 * @return  SleHalErrorCode
 *
 * @note    result returns in @link SleHalUpdateConnectParamReqCallback
 */
SleHalErrorCode SleConnectHalUpdateConnParam(const SleConnectionParamUpdate *param);

/**
 * brief   Set the connection buffer length.
 *
 * @param   [in] connectId                 - Indicates the ID of the SLE connect.
 * @param   [in] dataMaxLen                - Indicates the buffer length.
 * @return  SleHalErrorCode
 *
 * @note    result returns in @link SleHalUpdateConnectParamReqCallback
 */
SleHalErrorCode SleConnectHalSetDataLength(uint16_t connectId, uint16_t dataMaxLen);

/**
 * brief   Set sle phy param
 *
 * @param   [in] connectId                 - Indicates the ID of the SLE connect.
 * @param   [in] phy_param                 - Indicates Struct of sle phy parameter.
 * @return  SleHalErrorCode
 *
 * @note    result returns in @link SleHalSetPhyParamCallback
 */
SleHalErrorCode SleConnectHalSetPhyParam(uint16_t connectId, const SleConnectionPhyParam *phyParam);

/**
 * brief   Set sle mcs
 *
 * @param   [in] connectId                 - Indicates the ID of the SLE connect.
 * @param   [in] mcs                       - Indicates mcs Modulation and Coding Scheme.
 * @return  SleHalErrorCode
 *
 */
SleHalErrorCode SleConnectHalSetMcsValue(uint16_t connectId, uint8_t mcs);

/**
 * @brief   Authenticate with the remote device.
 *
 * @param   [in] address                - Indicates the remote device's address.
 * @return  SleHalErrorCode
 *
 * @note    result returns in @link SleHalAuthCompletedCallback
 */
SleHalErrorCode SleConnectHalSendPairReq(const SleDeviceAddress *address);

/**
 * @brief   Read the remote device's rssi.
 *
 * @param   [in] address                - Indicates the remote device's address.
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleConnectHalRemovePair(const SleDeviceAddress *address);

/**
 * @brief   Remove all paired devices.
 *
 * @param   None
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleConnectHalRemoveAllPairs(void);

/**
 * @brief   Get paired devices number.
 *
 * @param   [out] number                - Indicates the number of connected devices.
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleConnectHalGetPairedDevicesNum(uint16_t *number);

/**
 * @brief   Get paired devices number.
 *
 * @param   [out] pairedDevices         - Indicates connected devices.
 * @param   [out] number                - Indicates the number of connected devices.
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleConnectHalGetPairedDevices(SleDeviceAddress *pairedDevices, uint16_t *number);

/**
 * @brief   Get the connect state.
 *
 * @param   [in] connDevAddress         - Indicates the connected device's address.
 * @param   [out] state                 - Indicates the connect state {@link SlePairState}.
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleConnectHalGetPairState(const SleDeviceAddress *connDevAddress, SlePairState *state);

/**
 * @brief   Set the connect state change callback.
 *
 * @param   [in] callback               - Indicates the connect state change callback {@link SleConnectHalCallbacks}.
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleConnectHalRegisterCallbacks(const SleConnectHalCallbacks *callback);

/**
 * @brief   Set the connect state change callback.
 *
 * @param   [in] connectId               - connect Id
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleConnectHalReadRemoteRssi(uint16_t connectId);

/**
 * @brief   Set the default connect param.
 *
 * @param   [in] SleDefaultConnectionParam
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleConnectHalSetDefaultConnParam(const SleDefaultConnectionParam *defaultConnParam);

#ifdef __cplusplus
}
#endif

#endif //SLE_CONNECT_HAL_H